<template>
	<view class="j-number-box" :class="`size-${size}`">
		<view class="number-btn minus" @click="handleDecrease" :class="{ disabled: isMinDisabled }">
			<uv-icon name="minus" color="#fff" size="28rpx"></uv-icon>
		</view>

		<view class="number-input" v-if="showInput">
			<input type="number" v-model="currentValue" @input="handleInput" @blur="handleBlur" :disabled="disabled" class="input-field" />
		</view>

		<view class="number-btn plus" @click="handleIncrease" :class="{ disabled: isMaxDisabled }">
			<uv-icon name="plus" color="#fff" size="28rpx"></uv-icon>
		</view>
	</view>
</template>

<script>
export default {
	name: 'JNumberBox',
	props: {
		// 当前值
		value: {
			type: [Number, String],
			default: 1
		},
		// 最小值
		min: {
			type: Number,
			default: 1
		},
		// 最大值
		max: {
			type: Number,
			default: 999
		},
		// 步长
		step: {
			type: Number,
			default: 1
		},
		// 是否禁用
		disabled: {
			type: Boolean,
			default: false
		},
		// 是否显示输入框
		showInput: {
			type: Boolean,
			default: true
		},
		// 按钮大小
		size: {
			type: String,
			default: 'normal', // small, normal, large
			validator: (value) => ['small', 'normal', 'large'].includes(value)
		},
		// 按钮颜色
		color: {
			type: String,
			default: '#246ef9'
		},
		// 是否显示边框
		border: {
			type: Boolean,
			default: true
		},
		// 精度（小数点位数）
		precision: {
			type: Number,
			default: 0
		}
	},
	data() {
		return {
			currentValue: this.value
		};
	},
	computed: {
		// 是否禁用减少按钮
		isMinDisabled() {
			return this.disabled || this.currentValue <= this.min;
		},
		// 是否禁用增加按钮
		isMaxDisabled() {
			return this.disabled || this.currentValue >= this.max;
		}
	},
	watch: {
		value: {
			handler(newVal) {
				this.currentValue = newVal;
			},
			immediate: true
		}
	},
	methods: {
		// 格式化数值
		formatValue(value) {
			let num = parseFloat(value);
			if (isNaN(num)) {
				num = this.min;
			}

			// 限制在最小值和最大值之间
			num = Math.max(this.min, Math.min(this.max, num));

			// 处理精度
			if (this.precision > 0) {
				num = parseFloat(num.toFixed(this.precision));
			} else {
				num = Math.floor(num);
			}

			return num;
		},

		// 增加数量
		handleIncrease() {
			if (this.isMaxDisabled) return;

			const newValue = this.formatValue(this.currentValue + this.step);
			this.updateValue(newValue);
		},

		// 减少数量
		handleDecrease() {
			if (this.isMinDisabled) {
				// 可以执行删除操作
				this.$emit('delete', this.currentValue);
				return;
			}

			const newValue = this.formatValue(this.currentValue - this.step);
			this.updateValue(newValue);
		},

		// 输入框输入
		handleInput(e) {
			const value = e.detail.value;
			const newValue = this.formatValue(value);
			this.updateValue(newValue);
		},

		// 输入框失焦
		handleBlur(e) {
			const value = e.detail.value;
			const newValue = this.formatValue(value);
			this.updateValue(newValue);
			this.$emit('blur', e);
		},

		// 更新值
		updateValue(value) {
			if (value !== this.currentValue) {
				this.$nextTick(() => {
					this.currentValue = value;
					this.$emit('input', value);
					this.$emit('change', value);
				});
			}
		}
	}
};
</script>

<style lang="less" scoped>
.j-number-box {
	display: flex;
	align-items: center;
	justify-content: center;

	.number-btn {
		width: 60rpx;
		height: 60rpx;
		border-radius: 50%;
		display: flex;
		align-items: center;
		justify-content: center;
		transition: all 0.3s ease;
		cursor: pointer;

		&.minus {
			background: v-bind(color);
			color: #fff;
			border: 1rpx solid v-bind(color);

			&:not(.disabled):active {
				opacity: 0.8;
				transform: scale(0.95);
			}

			&.disabled:active {
				border: 1rpx solid v-bind(color);
			}

			&.disabled {
				background: #d9d9d9;
				color: #999;
				border-color: #d9d9d9;
				cursor: not-allowed;
			}
		}

		&.plus {
			background: v-bind(color);
			color: #fff;
			border: 1rpx solid v-bind(color);

			&:not(.disabled):active {
				opacity: 0.8;
				transform: scale(0.95);
			}

			&.disabled:active {
				border: 1rpx solid v-bind(color);
			}
			&.disabled {
				background: #d9d9d9;
				color: #999;
				border-color: #d9d9d9;
				cursor: not-allowed;
			}
		}

		.btn-text {
			font-size: 32rpx;
			font-weight: bold;
			line-height: 1;
		}
	}

	.number-input {
		margin: 0 10rpx;
		width: 70rpx;

		.input-field {
			width: 100%;
			height: 60rpx;
			text-align: center;
			font-size: 28rpx;
			color: #333;
			background: #fff;
			// border: 1rpx solid #e0e0e0;
			border-radius: 8rpx;
			box-sizing: border-box;

			&:focus {
				border-color: v-bind(color);
				outline: none;
			}

			&:disabled {
				background: #f5f5f5;
				color: #999;
				cursor: not-allowed;
			}
		}
	}
}

// 不同尺寸的样式调整
.j-number-box {
	&.size-small {
		.number-btn {
			width: 50rpx;
			height: 50rpx;

			.btn-text {
				font-size: 24rpx;
			}
		}

		.number-input {
			width: 80rpx;

			.input-field {
				height: 50rpx;
				font-size: 24rpx;
			}
		}
	}

	&.size-large {
		.number-btn {
			width: 70rpx;
			height: 70rpx;

			.btn-text {
				font-size: 36rpx;
			}
		}

		.number-input {
			width: 120rpx;

			.input-field {
				height: 70rpx;
				font-size: 32rpx;
			}
		}
	}
}
</style>
